#include "client_user_login_succcess_tool.h"
#include "log.h"
#include "client.h"
#include "clientmenu.h"

/* //打印菜单   || 群聊 私聊 加入购物车 移出购物车 清空购物车（如果商品不存在 商品数量不够情况） 
void print_menu(NOREAD a) {
    printf("请选择要进行的操作：\n");
    printf("1. 查看商品列表\n");
    printf("2. 购买商品\n");
    printf("3. 查看订单\n");
    printf("4. 取消订单\n");
    printf("5. 评价商品\n");
    printf("6. 查看评价\n");
   // printf("7. 加入商家活动群\n");
    printf("8. 咨询商家\n");
    printf("9. 查看个人信息\n");
    printf("10. 编辑个人信息\n");
    printf("11. 查看余额\n");
    printf("12. 提现\n");
    printf("13. 修改密码\n");
    printf("14. 充值账户\n");
    printf("15. 用户私聊\n");
    printf("16. 在线用户群聊\n");
    printf("17. 查看群聊\n");
    printf(". 私聊(%d)\n",a.siliao);
    printf(". 群聊(%d)\n",a.qunliao);
    
    printf("0. 退出\n");
    // 查看历史订单
}
 */

void print_menu(NOREAD a){
    printf("---------------（京东）请输入要进行的操作---------------\n");
    printf(" 订单管理       账号操作         信息管理    \n");
    printf("1.查看商品列表  9.查看个人信息   15.用户私聊 (%d) \n",a.qunliao );
    printf("2.购买商品     10.编辑个人信息   16.在线用户群聊(%d)\n",a.siliao);
    printf("3.查看订单     11.查看余额       17.查看群聊\n");
    printf("4.取消订单     12.提现           18.加入群聊\n" );
    printf("5.评价商品     13.修改密码       19.进入群聊\n");
    printf("6.查看评价     14.充值账户        20.查看未读消息\n" );
}

//查看未读消息的条数
NOREAD view_noread_msg(int fd){
    MSG msg = {0 };
    msg.type = _view_chat_noread;
    memcpy(msg.data,currentLoginUserName,sizeof(currentLoginUserName));
    
    send(fd , &msg , sizeof(msg) ,0);
    recv(fd , &msg , sizeof(msg) , 0);
    printf("%s\n",msg.data);
    // 解析响应数据
    NOREAD a;
    if (sscanf(msg.data, "siliao=%d qunliao=%d", &a.siliao, &a.qunliao) != 2) {
        ERROR("无法解析服务器响应: %s\n", msg.data);
        a.siliao = 0;
        a.qunliao = 0;
    }
    return a;
}

//用户登录成功界面
void user_login_success(int fd){
    //用户登录成功 发送给服务器一个消息 查看 当前 用户 有 多少个 私聊 或者 群聊 的 未读消息
    NOREAD a = view_noread_msg(fd);

    int choice;

    while (1)
    {
       //system("clear"); // 清屏，对于 Windows 使用 system("cls")
        print_menu(a);
        printf("请输入选项: ");
        if (scanf("%d", &choice) != 1) { // 检查输入是否为整数
            printf("无效的输入，请输入一个数字。\n");
            while (getchar() != '\n'); // 清除输入缓冲区
            continue;
        }
        while (getchar() != '\n');
        
        switch (choice) {
            case 1: // 查看商品列表
                view_products(fd); // 显示所有可用的商品
                break;
            case 2: // 购买商品
                buy_product(fd); // 允许用户选择并购买商品
                break;
            case 3: // 查看订单
                view_orders(fd); // 展示用户的订单历史
                break;
          case 4: // 取消订单
                cancel_order(fd); // 允许用户取消现有的订单
                break;
              case 5: // 评价商品
                review_product(fd); // 用户可以对已购商品进行评价
                break;
           case 6:    //查看别人对某商家某产品的 评价
                view_reviews( fd);
                break;
             case 7: // 加入商家群
                join_merchant_group(fd); // 用户加入特定商家的活动群聊
                break;
                 
            case 8: // 咨询商家
                consult_merchant(fd); // 用户可以向商家提出问题或咨询
                break; 
                
               
            case 9: // 查看个人信息
                view_personal_info(fd); // 显示用户的个人资料信息
                break;
            case 10: // 编辑个人信息
                edit_personal_info(fd); // 用户可以编辑和更新自己的个人信息
                break;
            case 11: // 查看余额
                check_balance(fd); // 查询用户的账户余额
                break;
            case 12: // 提现
                withdraw_money(fd); // 用户可以从账户中提取资金
                break;
            case 13: // 修改密码
                change_password(fd); // 用户可以更改自己的登录密码
                break;
            case 14: // 充值账户
                recharge_account(fd); // 用户可以向账户充值
                break;
            case 15: // 用户私聊
                singleChatFun(fd); 
                break;
            case 16: // 用户群聊
                groupChatFun(fd); 
                break;
            case 17: // 用户 查看 群聊
                client_view_merchant_group(fd); 
                break;
            case 18: // 用户 查看 群聊
                join_merchant_group(fd); 
                break;
            case 19: // 用户  群聊
                client_insert_merchant_group(fd); 
                break;
            case 0: // 退出
                printf("感谢使用，再见！\n");
                exit(0);
                break;
            default:
                printf("无效的选择，请重新输入。\n");
                break;
        }
    }
    
}

//聊天用的线程
void *readChat(void *pData)
{
     int fd = *(int *)pData; // 还原套接字
     while (1)
     {
          MSG msg;
          // 接受群聊消息
          recv(fd, &msg, sizeof(msg), 0);
          if(msg.type == groupChat)
          {
              printf("收到群聊消息：%s\n", msg.data); 
          }
          else if(msg.type == singleChat)
          {
               SC * pSC = (SC *)msg.data;
               printf("%s发来消息，内容是：%s\n",pSC->self,pSC->text);
          }
          else if(msg.type == _msgChar)
          {
               SC * pSC = (SC *)msg.data;
               printf("商家 %s发来消息，内容是：%s\n",pSC->self,pSC->text);
          }
          else if(msg.type == _insert_merchant_group)
          {
                //SC * pSC = (SC *)msg.data;
               //printf("商家群中的 %s发来消息，内容是：%s\n",pSC->self,pSC->text);
                printf("收到商家群聊消息：%s\n", msg.data); 
          }
     }
}
//在线用户（商家 和 用户 ）群聊实现
void groupChatFun(int fd)
{
     pthread_t pt;
     pthread_create(&pt, NULL, readChat, &fd); // 创建一个接收聊天信息用的线程
     while (1)
     {
          printf("请输入消息内容\n");
          MSG msg;
          msg.type = groupChat;  // 消息类型为群聊
          scanf("%s", msg.data); // 输入消息内容

          // 把消息发送给服务器
          send(fd, &msg, sizeof(msg), 0);

          if (strcmp(msg.data, "quit") == 0) // 如果用户输入quit，说明想退出聊天
          {
               pthread_cancel(pt); // 关闭接受聊天信息用的线程，避免它接受走了其它不想管的消息
               break;
          }
     }
}
//用户私聊实现函数
void singleChatFun(int fd)
{
     pthread_t pt;
     pthread_create(&pt, NULL, readChat, &fd); // 创建一个接收聊天信息用的线程

     while (1)
     {
          SC sc;//私聊的结构体
          strcpy(sc.self,currentLoginUserName);//把当前登录的用户作为发送方
          printf("请输入对方的名字:\n");
          scanf("%s",sc.dest);//填写对方的名字
          printf("请输入聊天的内容:\n");
          scanf("%s",sc.text);//填写对方的名字

          MSG msg;
          msg.type = singleChat;
          memcpy(msg.data,&sc,sizeof(sc));//把填好的私聊结构体拷贝到消息结构体中
          send(fd,&msg,sizeof(msg),0);//把带有私聊信息的结构体发给服务器

          if (strcmp(sc.text, "quit") == 0) // 如果用户输入quit，说明想退出聊天
          {
               pthread_cancel(pt); // 关闭接受聊天信息用的线程，避免它接受走了其它不想管的消息
               break;
          }
     }
     //这里应该要写一个recv去接受服务器的返回，判断是否发送成功了
}

// 查看商品列表
void view_products(int fd) {
    MSG msg = {0};
     msg.type = _view_products;
     // 把消息发送给服务器
     if (send(fd, &msg, sizeof(msg), 0) < 0) {
        perror("发送消息失败");
        return ;
     }

     //循环接收商品列表
     while(1)
     {
          ssize_t bytes_received = recv(fd, &msg, sizeof(msg), 0);
        if (bytes_received <= 0) {
            if (bytes_received == 0) {
                printf("连接已关闭。\n");
            } else {
                perror("接收消息失败");
            }
            break;
        }

        if (msg.type == over) {
            break;
        }
        if(msg.type == _no)
        {
            printf("%s",msg.data);
            break;
        }
        // 安全地复制数据到临时缓冲区，并转换为 PRODUCT 结构体
        PRODUCT product;
        memcpy(&product, msg.data, sizeof(PRODUCT));

        // 打印商品信息
        printf("商品id: %d 商家：%s 商品名：%s 商品价格：%d 商品数量：%d\n",
               product.id,
               product.merchant_name,
               product.product_name,
               product.product_val,
               product.product_num);
          
    //       PRODUCT * product = (PRODUCT *)msg.data;//把消息结构体的地址转为商品结构体
    //       printf("商家：%s 商品名：%s 商品价格：%d 商品数量：%d \n",product->merchant_name,
    //       product->product_name,product->product_val,product->product_num);
    
    }
    printf("所有商品信息已显示完毕。\n");
}

// 购买商品 通过商品 id 和 数量 比较 然后 看看 余额是不是足够 然后生成订单
void buy_product(int fd) {
    printf("请输入要购买的商品 的 id：");
    char productId[16];
    if (scanf("%s", productId) != 1) {
        printf("无效的商品ID。\n");
        return;
    }
    while (getchar() != '\n');
    printf("请输入购买数量: ");
    int quantity;
    if (scanf("%d", &quantity) != 1 || quantity <= 0) {
        printf("无效的数量。\n");
        return;
    }
    while (getchar() != '\n'); // 清除输入缓冲区

    // 构建购买请求消息
    MSG msg = { .type = _buy_product };
    snprintf(msg.data, sizeof(msg.data), "%s %d", productId, quantity);

    SendsigtoServe(msg, fd);
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("购买成功！\n");
    } else {
        printf("购买失败。原因是%s\n",response.data);
    }
}

// 查看订单
void view_orders(int fd) {
    // 构建查看订单请求消息
    MSG msg = { .type = _view_orders };
    // 发送请求到服务器
    SendsigtoServe(msg, fd);
    // 接收服务器响应
    //循环接收商品列表
     while(1)
     {
         if (recv(fd, &msg, sizeof(msg), 0) <= 0) {
            perror("接收消息失败");
            return;
        }
        if (msg.type == over) {
            break;
        }
          // 如果不是结束信号，则打印订单信息
        if (msg.type == _yes) {
            printf("%s\n", msg.data);
        } else {
            // 处理错误情况
            printf("服务器响应: %s\n", msg.data);
            break;
        }
        }
     printf("以上是您的订单\n");
}

// 取消订单
void cancel_order(int fd) {
    printf("请输入要取消的订单ID：  ");
    char orderId[16];
    scanf("%s", orderId);
    while (getchar() != '\n');

    MSG msg = { .type = _cancel_order  };
    snprintf(msg.data, sizeof(msg.data), "%s", orderId);
    SendsigtoServe(msg, fd);
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("订单已取消%s\n",response.data);
    } else {
        printf("取消订单失败。原因是%s\n",response.data);
    }
}

// 评价商品
void review_product(int fd) {



    // 初始化 CHAR 结构体
    CHAR char_msg = {0};

     // 收集用户输入
    printf("请输入要评价的商品的 商家 和 商品的ID（格式：商家名 商品ID）：");
    scanf("%s%s",char_msg.name,char_msg.id);
    //while (getchar() != '\n'); // 清除输入缓冲区
    
    printf("请撰写评价内容（不超过512字节）：");
    //fgets(char_msg.data, sizeof(char_msg.data), stdin);
    //char_msg.data[strcspn(char_msg.data, "\n")] = 0; // 去掉换行符
    scanf("%s",char_msg.data);

    // 构造 MSG 结构体
    MSG msg = { .type = _review_product };
    memcpy(msg.data , &char_msg , sizeof(char_msg));
    //snprintf(msg.data, sizeof(msg.data), "%s %s %s", char_msg.name, char_msg.id, char_msg.data);

    printf("发送评价中\n");
    // 发送评价请求到服务器
    send(fd, &msg, sizeof(msg), 0);

    // 接收服务器响应
    MSG response;
    response = RecvsigtoServe(response, fd);

    if (response.type == _yes) {
        printf("评价已提交。\n");
    } else {
        printf("评价提交失败。原因是%s\n",response.data);
    }
}

// 查看评价
void view_reviews(int fd) {
    // 初始化 CHAR 结构体
    CHAR char_msg = {0};

    // 收集用户输入
    printf("请输入要查看评价的商品的 商家 和 商品的ID（格式：商家名 商品ID）：");
    scanf("%63s %63s", char_msg.name, char_msg.id); // 分别存储商家名和商品ID
    while (getchar() != '\n'); // 清除输入缓冲区

    // 构造 MSG 结构体
    MSG msg = { .type = _view_reviews };
    snprintf(msg.data, sizeof(msg.data), "%s %s", char_msg.name, char_msg.id);

    // 发送查看评价请求到服务器
    send(fd, &msg, sizeof(MSG), 0);

     //循环接收商品列表
     while(1)
     {
         if (recv(fd, &msg, sizeof(msg), 0) <= 0) {
            perror("接收消息失败");
            return;
        }
        if (msg.type == over) {
            break;
        }
          // 如果不是结束信号，则打印订单信息
        if (msg.type == _yes) {
            printf("%s\n", msg.data);
        } else {
            // 处理错误情况
            printf("服务器响应: %s\n", msg.data);
            break;
        }
    }
     printf("以上是相关订单的评价\n");
}

// 退货
/* void return_goods(int fd) {
    printf("请输入要退货的订单ID：");
    char orderId[MAX_FDS];
    scanf("%s", orderId);
    while (getchar() != '\n');

    MSG msg = { .type = _msgChar, .data = orderId };
    SendsigtoServe(msg, fd);
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("退货申请已提交，请等待处理。\n");
    } else {
        printf("退货申请提交失败。\n");
    }
}
 */

// 查看商家活动群
void client_view_merchant_group(int fd) {
    //客户端发送消息 
    MSG msg = { .type = _view_merchant_group };
    //发送
    // 发送请求给服务器
    send(fd, &msg, sizeof(msg), 0);
    // 然后循环 接收 直到 发来 over
    // 接收响应
    MSG buffer = {0};
    while (1) {
        int bytes_received = recv(fd, &buffer, sizeof(buffer), 0);
        if (bytes_received <= 0) {
            fprintf(stderr, "Connection closed or error occurred.\n");
            break;
        }

        // 检查是否是结束信号
        if ( buffer.type == over ) {
            printf("群聊列表结束。\n");
            break;
        }

        // 检查是否是有信号
        if ( buffer.type ==  _no ) {
            printf(" 没有群聊 \n");
            break;
        }

        // 打印接收到的群聊信息
        // 打印接收到的群聊信息
        if (buffer.type == _yes) {
            printf("%s\n", buffer.data);
        } else {
            // 如果接收到未知类型的消息，可以打印警告并继续
            printf("收到未知类型的消息: %d\n", buffer.type);
        }

       
    }
    printf("上面是已经有的群聊列表 打印结束\n");
    
}

// 加入商家活动群
void join_merchant_group(int fd) {
    
    //客户端发送消息 
    MSG msg = { .type = _join_merchant_group };

    SC sc;//私聊的结构体
    strcpy(sc.self,currentLoginUserName);//把当前登录的用户作为发送方
    printf("请输入你要加入的群聊的名字:\n");
    scanf("%s",sc.dest);//填写对方的名字 服务器就在 用户的 表中找对应的套接字
    
     memcpy(msg.data,&sc,sizeof(sc));//把填好的 结构体拷贝到消息结构体中
    

    // 发送请求给服务器
    send(fd, &msg, sizeof(msg), 0);
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("加入群聊成功\n" );
    } else {
        printf("加入群聊失败 原因是：%s\n", response.data);
    }
    
}

//用户 群聊  发消息
void client_insert_merchant_group(int fd){
    //线程收
    pthread_t pt;
     pthread_create(&pt, NULL, readChat, &fd); // 创建一个接收聊天信息用的线程
    while (1)
    {
        //消息类型 构建
        SC sc;//私聊的结构体
        strcpy(sc.self,currentLoginUserName);//把当前登录的用户作为发送方
        printf("请输入群聊的名字:\n");
        scanf("%s",sc.dest);//填写群的名字
        printf("请输入聊天的内容:\n");
        scanf("%s",sc.text);
        //发送的群聊
        //循环发送
        MSG msg;
        msg.type = _insert_merchant_group;
        memcpy(msg.data,&sc,sizeof(sc));//把填好的私聊结构体拷贝到消息结构体中
        send(fd,&msg,sizeof(msg),0);//把带有私聊信息的结构体发给服务器

        if (strcmp(sc.text, "quit") == 0) // 如果用户输入quit，说明想退出聊天
        {
            pthread_cancel(pt); // 关闭接受聊天信息用的线程，避免它接受走了其它不想管的消息
            break;
        }
    }
}

// 咨询商家
void consult_merchant(int fd) {
     pthread_t pt;
     pthread_create(&pt, NULL, readChat, &fd); // 创建一个接收聊天信息用的线程
    while (1)
    {
    

        SC sc;//私聊的结构体
        strcpy(sc.self,currentLoginUserName);//把当前登录的用户 作为发送方
        printf("请输入商家的名字:\n");
        scanf("%s",sc.dest);//填写对方的名字

        printf("请输入你想咨询的问题：（不超过500字）");
        scanf("%s",sc.text);

        MSG msg;
        msg.type = _msgChar;
        memcpy(msg.data,&sc,sizeof(sc));//把填好的私聊结构体拷贝到消息结构体中
        send(fd,&msg,sizeof(msg),0);//把带有私聊信息的结构体发给服务器
    }
    
}


// 查看个人信息
void view_personal_info(int fd) {
    MSG msg = { .type = _view_personal_info, .data = "view personal info" };
    SendsigtoServe(msg, fd);
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("个人信息:\n%s\n", response.data);
    } else {
        printf("无法获取个人信息 原因是：%s\n", response.data);
    }
}

// 编辑个人信息
void edit_personal_info(int fd) {
    // 初始化 REGIST 结构体
    REGIST reg = {0};

    // 收集用户输入的新账号、密码和手机号
    printf("请输入新的用户名（不超过128字符）：");
    scanf("%127s", reg.name); // 新用户名
    while (getchar() != '\n'); // 清除输入缓冲区

    printf("请输入新的密码（不超过128字符）：");
    scanf("%127s", reg.pwd); // 新密码
    while (getchar() != '\n'); // 清除输入缓冲区

    printf("请输入新的电话号码（不超过16字符）：");
    scanf("%15s", reg.find); // 新电话号码
    while (getchar() != '\n'); // 清除输入缓冲区

    // 构造 MSG 结构体
    MSG msg = { .type = _edit_personal_info };
    snprintf(msg.data, sizeof(msg.data), "%s %s %s", reg.name, reg.pwd, reg.find);

    // 发送修改个人信息请求到服务器
    send(fd, &msg, sizeof(MSG), 0);

    // 接收服务器响应
    MSG response;
    response=RecvsigtoServe(response, fd);

    if (response.type == _yes) {
        printf("个人信息已成功修改。\n");
    } else {
        printf("未能修改个人信息。原因是：%s\n", response.data);
    }
}
 
// 查看余额
void check_balance(int fd) {
    // 构造 MSG 结构体
    MSG msg = { .type = _check_balance };

    // 发送查看余额请求到服务器
    send(fd, &msg, sizeof(MSG), 0);

    // 接收服务器响应
    MSG response;
    response=RecvsigtoServe( response, fd);

    if (response.type == _yes) {
        printf("您的余额是：%s\n", response.data);
    } else {
        printf("未能查询余额。原因是：%s\n", response.data);
    }
}

// 提现
void withdraw_money(int fd) {
    int amount;

    // 收集用户输入的提现金额
    printf("请输入提现金额：");
    scanf("%d", &amount); // 提现金额
    while (getchar() != '\n'); // 清除输入缓冲区

    MSG msg = { .type = _tixian};
    snprintf(msg.data, sizeof(msg.data), "%d", amount);
    
    SendsigtoServe(msg, fd);
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("提现申请已提交，请等待处理。\n");
    } else {
        printf("提现申请提交失败。原因是：%s\n", response.data);
    }
}

// 修改密码
void change_password(int fd) {
    char oldPwd[128], newPwd[128];

    // 收集用户输入的旧密码和新密码
    printf("请输入当前密码（不超过128字符）：");
    scanf("%127s", oldPwd); // 当前密码
    while (getchar() != '\n'); // 清除输入缓冲区

    printf("请输入新密码（不超过128字符）：");
    scanf("%127s", newPwd); // 新密码
    while (getchar() != '\n'); // 清除输入缓冲区

     
     // 构造 MSG 结构体
    MSG msg = { .type = _withdraw_money }; // 错误类型，应为 _edit_personal_info 或自定义类型
    snprintf(msg.data, sizeof(msg.data), "%s %s", oldPwd, newPwd);

    // 发送修改密码请求到服务器
    send(fd, &msg, sizeof(MSG), 0);

    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("密码修改成功。\n");
    } else {
        printf("密码修改失败。原因是：%s\n", response.data);
    }
}

// 充值账户
void recharge_account(int fd) { 
    int amount;

    // 收集用户输入的充值金额
    printf("请输入充值金额：");
    scanf("%d", &amount); // 充值金额
    while (getchar() != '\n'); // 清除输入缓冲区

   // 构造 MSG 结构体
    MSG msg = { .type = _recharge_account };
    snprintf(msg.data, sizeof(msg.data), "%d", amount);

    // 发送充值请求到服务器
    send(fd, &msg, sizeof(MSG), 0);
    
    MSG response = RecvsigtoServe(msg, fd);
    if (response.type == _yes) {
        printf("充值成功！\n");
    } else {
        printf("充值失败。原因是：%s\n", response.data);
    }
}



 